﻿using gt.rediscachemanager.Entry;
using StackExchange.Redis;
using System;
using System.Globalization;
using System.Threading.Tasks;

namespace gt.rediscachemanager.Core.Executor
{
    internal class StackExchangeRedisExecutor : IRedisExecutor
    {
        private IConnectionMultiplexer m_connection;
        private int m_db = -1;

        public StackExchangeRedisExecutor(IConnectionMultiplexer conn, int db = -1)
        {
            this.m_connection = conn;
            this.m_db = -1;
        }

        public TResult ExecuteCommand<T, TResult>(Entry.RedisCommand command, Entry.RedisMessageWrapper<T, TResult> message, CommandFlags commandFlags)
        {
            dynamic commandMessage = message;
            if (commandMessage == null) throw new InvalidOperationException("command get a error message type！");
            switch (command)
            {
                case RedisCommand.Info:
                    commandMessage.Result = ((IServer)this.m_connection.GetServer(commandMessage.Value)).InfoRaw();
                    break;
                case RedisCommand.ClientList:
                    commandMessage.Result = ((IServer)this.m_connection.GetServer(commandMessage.Value)).ClientList();
                    break;
                case RedisCommand.StringGet:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringGet(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.StringGetSet:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringGetSet(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.StringSet:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringSet(commandMessage.Key, commandMessage.Value, commandMessage.ExpiredTime,
                        commandMessage.When, commandFlags);
                    break;
                case RedisCommand.StringSetArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringSet(commandMessage.Value, When.Always, commandFlags);
                    break;
                case RedisCommand.StringAppend:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringAppend(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.StringIncrement:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringIncrement(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.KeyExists:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).KeyExists(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.KeyRemove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).KeyDelete(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.KeyRemoveArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).KeyDelete((RedisKey[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.KeyExpired:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).KeyExpire(commandMessage.Key, commandMessage.ExpiredTime, commandFlags);
                    break;
                case RedisCommand.KeyTimeToLive:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).KeyTimeToLive(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.HashGet:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashGet(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HashGetByArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashGet(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HashGetAll:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashGetAll(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.HashSet:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashSet(commandMessage.Key, commandMessage.Value.Name, commandMessage.Value.Value, commandMessage.When, commandFlags);
                    break;
                case RedisCommand.HashSetArray:
                    this.m_connection.GetDatabase(m_db).HashSet(commandMessage.Key, commandMessage.Value, commandFlags);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.HashExist:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashExists(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HashRemove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashDelete(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HashRemoveArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashDelete(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HashIncrement:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashIncrement(commandMessage.Key, commandMessage.Value.Name,
                        long.Parse(commandMessage.Value.Value, CultureInfo.CurrentCulture), commandFlags);
                    break;
                case RedisCommand.HashScan:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashScan(commandMessage.Key,
                        commandMessage.Scan.FieldPattern ?? RedisValue.Null, commandMessage.Scan.PageSize, commandMessage.Scan.Cursor, commandMessage.Scan.PageOffset, commandFlags);
                    break;
                case RedisCommand.HashFields:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashKeys(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.HashValues:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashValues(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.HashLength:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HashLength(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.ListGetByIndex:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListGetByIndex(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.ListInsertAfter:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListInsertAfter(commandMessage.Key, commandMessage.Value.Pivot,
                        commandMessage.Value.InsertValue, commandFlags);
                    break;
                case RedisCommand.ListInsertBefore:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListInsertBefore(commandMessage.Key, commandMessage.Value.Pivot,
                        commandMessage.Value.InsertValue, commandFlags);
                    break;
                case RedisCommand.ListLeftPop:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListLeftPop(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.ListLeftPush:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListLeftPush(commandMessage.Key, commandMessage.Value,
                        When.Always, commandFlags);
                    break;
                case RedisCommand.ListLength:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListLength(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.ListRange:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListRange(commandMessage.Key, commandMessage.Value.FirstIndex,
                        commandMessage.Value.SecondIndex, commandFlags);
                    break;
                case RedisCommand.ListRightPop:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListRightPop(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.ListRightPush:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListRightPush(commandMessage.Key, commandMessage.Value,
                       commandMessage.When, commandFlags);
                    break;
                case RedisCommand.ListSetByIndex:
                    this.m_connection.GetDatabase(m_db).ListSetByIndex(commandMessage.Key, commandMessage.Value.FirstIndex, commandMessage.Value.InsertValue, commandFlags);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.ListTrim:
                    this.m_connection.GetDatabase(m_db).ListTrim(commandMessage.Key, commandMessage.Value.FirstIndex, commandMessage.Value.SecondIndex, commandFlags);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.ListRemove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).ListRemove(commandMessage.Key, commandMessage.Value.Value, commandMessage.Value.Count, commandFlags);
                    break;
                case RedisCommand.LockTake:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).LockTake(commandMessage.Key, commandMessage.Value, commandMessage.ExpiredTime, commandFlags);
                    break;
                case RedisCommand.LockQuery:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).LockQuery(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.LockRelease:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).LockRelease(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetAdd:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetAdd(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetAddArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetAdd(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetCombine:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetCombine(commandMessage.Value.Operation, commandMessage.Value.First, commandMessage.Value.Second, commandFlags);
                    break;
                case RedisCommand.SetCombineAndStore:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetCombineAndStore(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags);
                    break;
                case RedisCommand.SetCombineAndStoreArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetCombineAndStore(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.Keys, commandFlags);
                    break;
                case RedisCommand.SetCombineArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetCombine(commandMessage.Value.Operation, commandMessage.Value.Keys, commandFlags);
                    break;
                case RedisCommand.SetContains:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetContains(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetLength:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetLength(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.SetMembers:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetMembers(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.SetMove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetMove(commandMessage.Value.Source, commandMessage.Value.Destination, commandMessage.Value.Value, commandFlags);
                    break;
                case RedisCommand.SetPop:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetPop(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.SetRandomMember:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetRandomMember(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.SetRandomMembers:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetRandomMembers(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetRemove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetRemove(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SetRemoveArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SetRemove(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.SortedSetAdd:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetAdd(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.Score, commandMessage.When, commandFlags);
                    break;
                case RedisCommand.SortedSetDecrement:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetDecrement(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.IncreOrDecreValue, commandFlags);
                    break;
                case RedisCommand.SortedSetIncrement:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetIncrement(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.IncreOrDecreValue, commandFlags);
                    break;
                case RedisCommand.SortedSetLength:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetLength(commandMessage.Key, commandMessage.Value.Min, commandMessage.Value.Max, commandMessage.Value.Exclude, commandFlags);
                    break;
                case RedisCommand.SortedSetRangeByRank:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetRangeByRank(commandMessage.Key, commandMessage.Value.Start, commandMessage.Value.Stop, commandMessage.Value.Order, commandFlags);
                    break;
                case RedisCommand.SortedSetRangeByScore:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetRangeByScore(commandMessage.Key, commandMessage.Value.ScoreStart, commandMessage.Value.ScoreStop, commandMessage.Value.Exclude, commandMessage.Value.Order, commandMessage.Value.Skip, commandMessage.Value.Take, commandFlags);
                    break;
                case RedisCommand.SortedSetRemove:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).SortedSetRemove(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HyperLogLogAdd:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HyperLogLogAdd(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HyperLogLogAddArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HyperLogLogAdd(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HyperLogLogLength:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HyperLogLogLength(commandMessage.Key, commandFlags);
                    break;
                case RedisCommand.HyperLogLogLengthArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).HyperLogLogLength((RedisKey[])commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.HyperLogLogMerge:
                    this.m_connection.GetDatabase(m_db).HyperLogLogMerge(commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.HyperLogLogMergeArray:
                    this.m_connection.GetDatabase(m_db).HyperLogLogMerge(commandMessage.Value.Destination, commandMessage.Value.SourceKeys, commandFlags);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.StringBitCount:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringBitCount(commandMessage.Key, commandMessage.Value.Start, commandMessage.Value.End, commandFlags);
                    break;
                case RedisCommand.StringBitOperation:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringBitOperation(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags);
                    break;
                case RedisCommand.StringBitOperationArray:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringBitOperation(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.Keys, commandFlags);
                    break;
                case RedisCommand.StringBitPosition:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringBitPosition(commandMessage.Key, commandMessage.Value.Bit, commandMessage.Value.Start, commandMessage.Value.End, commandFlags);
                    break;
                case RedisCommand.StringGetBit:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringGetBit(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.StringSetBit:
                    commandMessage.Result = this.m_connection.GetDatabase(m_db).StringSetBit(commandMessage.Key, commandMessage.Value.Offset, commandMessage.Value.Bit, commandFlags);
                    break;
                default:
                    throw new InvalidOperationException("execute command do not support this:" + command.ToString());
            }
            return message.Result == null ? default(TResult) : message.Result;
        }

        public async Task<TResult> ExecuteCommandAsync<T, TResult>(Entry.RedisCommand command, Entry.RedisMessageWrapper<T, TResult> message, CommandFlags commandFlags)
        {
            dynamic commandMessage = message;
            IDatabaseAsync db = this.m_connection.GetDatabase(m_db) as IDatabaseAsync;      //由于上面dynamic的原因，此处需要显示转换成 IDatabaseAsync
            if (commandMessage == null) throw new InvalidOperationException("command get a error message type！");
            switch (command)
            {
                case RedisCommand.StringGet:
                    commandMessage.Result = await db.StringGetAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringGetSet:
                    commandMessage.Result = await db.StringGetSetAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSet:
                    commandMessage.Result = await db.StringSetAsync(commandMessage.Key, commandMessage.Value, commandMessage.ExpiredTime,
                        commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSetArray:
                    commandMessage.Result = await db.StringSetAsync(commandMessage.Value, commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringAppend:
                    commandMessage.Result = await db.StringAppendAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringIncrement:
                    commandMessage.Result = await db.StringIncrementAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyExists:
                    commandMessage.Result = await db.KeyExistsAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyRemove:
                    commandMessage.Result = await db.KeyDeleteAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyRemoveArray:
                    commandMessage.Result = await db.KeyDeleteAsync((RedisKey[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyExpired:
                    commandMessage.Result = await db.KeyExpireAsync(commandMessage.Key, commandMessage.ExpiredTime, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyTimeToLive:
                    commandMessage.Result = await db.KeyTimeToLiveAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGet:
                    commandMessage.Result = await db.HashGetAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGetByArray:
                    commandMessage.Result = await db.HashGetAsync(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGetAll:
                    commandMessage.Result = await db.HashGetAllAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashSet:
                    commandMessage.Result = await db.HashSetAsync(commandMessage.Key, commandMessage.Value.Name, commandMessage.Value.Value, commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashSetArray:
                    await db.HashSetAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.HashExist:
                    commandMessage.Result = await db.HashExistsAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashRemove:
                    commandMessage.Result = await db.HashDeleteAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashRemoveArray:
                    commandMessage.Result = await db.HashDeleteAsync(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashIncrement:
                    commandMessage.Result = await db.HashIncrementAsync(commandMessage.Key, commandMessage.Value.Name,
                        long.Parse(commandMessage.Value.Value, CultureInfo.CurrentCulture), commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashFields:
                    commandMessage.Result = await db.HashKeysAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashValues:
                    commandMessage.Result = await db.HashValuesAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HashLength:
                    commandMessage.Result = await db.HashLengthAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListGetByIndex:
                    commandMessage.Result = await db.ListGetByIndexAsync(commandMessage.Key, commandMessage.Value, commandFlags);
                    break;
                case RedisCommand.ListInsertAfter:
                    commandMessage.Result = await db.ListInsertAfterAsync(commandMessage.Key, commandMessage.Value.Pivot,
                        commandMessage.Value.InsertValue, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListInsertBefore:
                    commandMessage.Result = await db.ListInsertBeforeAsync(commandMessage.Key, commandMessage.Value.Pivot,
                        commandMessage.Value.InsertValue, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLeftPop:
                    commandMessage.Result = await db.ListLeftPopAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLeftPush:
                    commandMessage.Result = await db.ListLeftPushAsync(commandMessage.Key, commandMessage.Value,
                        commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLength:
                    commandMessage.Result = await db.ListLengthAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRange:
                    commandMessage.Result = await db.ListRangeAsync(commandMessage.Key, commandMessage.Value.FirstIndex,
                        commandMessage.Value.SecondIndex, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRightPop:
                    commandMessage.Result = await db.ListRightPopAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRightPush:
                    commandMessage.Result = await db.ListRightPushAsync(commandMessage.Key, commandMessage.Value,
                        commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.ListSetByIndex:
                    await db.ListSetByIndexAsync(commandMessage.Key, commandMessage.Value.FirstIndex, commandMessage.Value.InsertValue, commandFlags).ConfigureAwait(false);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.ListTrim:
                    await db.ListTrimAsync(commandMessage.Key, commandMessage.Value.FirstIndex, commandMessage.Value.SecondIndex, commandFlags).ConfigureAwait(false);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.ListRemove:
                    commandMessage.Result = await db.ListRemoveAsync(commandMessage.Key, commandMessage.Value.Value, commandMessage.Value.Count, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetAdd:
                    commandMessage.Result = await db.SetAddAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetAddArray:
                    commandMessage.Result = await db.SetAddAsync(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombine:
                    commandMessage.Result = await db.SetCombineAsync(commandMessage.Value.Operation, commandMessage.Value.First, commandMessage.Value.Second, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineAndStore:
                    commandMessage.Result = await db.SetCombineAndStoreAsync(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineAndStoreArray:
                    commandMessage.Result = await db.SetCombineAndStoreAsync(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.Keys, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineArray:
                    commandMessage.Result = await db.SetCombineAsync(commandMessage.Value.Operation, commandMessage.Value.Keys, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetContains:
                    commandMessage.Result = await db.SetContainsAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetLength:
                    commandMessage.Result = await db.SetLengthAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetMembers:
                    commandMessage.Result = await db.SetMembersAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetMove:
                    commandMessage.Result = await db.SetMoveAsync(commandMessage.Value.Source, commandMessage.Value.Destination, commandMessage.Value.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetPop:
                    commandMessage.Result = await db.SetPopAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRandomMember:
                    commandMessage.Result = await db.SetRandomMemberAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRandomMembers:
                    commandMessage.Result = await db.SetRandomMembersAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRemove:
                    commandMessage.Result = await db.SetRemoveAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRemoveArray:
                    commandMessage.Result = await db.SetRemoveAsync(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetAdd:
                    commandMessage.Result = await db.SortedSetAddAsync(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.Score, commandMessage.When, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetDecrement:
                    commandMessage.Result = await db.SortedSetDecrementAsync(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.IncreOrDecreValue, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetIncrement:
                    commandMessage.Result = await db.SortedSetIncrementAsync(commandMessage.Key, commandMessage.Value.Member, commandMessage.Value.IncreOrDecreValue, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetLength:
                    commandMessage.Result = await db.SortedSetLengthAsync(commandMessage.Key, commandMessage.Value.Min, commandMessage.Value.Max, commandMessage.Value.Exclude, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRangeByRank:
                    commandMessage.Result = await db.SortedSetRangeByRankAsync(commandMessage.Key, commandMessage.Value.Start, commandMessage.Value.Stop, commandMessage.Value.Order, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRangeByScore:
                    commandMessage.Result = await db.SortedSetRangeByScoreAsync(commandMessage.Key, commandMessage.Value.ScoreStart, commandMessage.Value.ScoreStop, commandMessage.Value.Exclude, commandMessage.Value.Order, commandMessage.Value.Skip, commandMessage.Value.Take, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRemove:
                    commandMessage.Result = await db.SortedSetRemoveAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogAdd:
                    commandMessage.Result = await db.HyperLogLogAddAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogAddArray:
                    commandMessage.Result = await db.HyperLogLogAddAsync(commandMessage.Key, (RedisValue[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogLength:
                    commandMessage.Result = await db.HyperLogLogLengthAsync(commandMessage.Key, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogLengthArray:
                    commandMessage.Result = await db.HyperLogLogLengthAsync((RedisKey[])commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogMerge:
                    await db.HyperLogLogMergeAsync(commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags).ConfigureAwait(false);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.HyperLogLogMergeArray:
                    await db.HyperLogLogMergeAsync(commandMessage.Value.Destination, commandMessage.Value.SourceKeys, commandFlags).ConfigureAwait(false);
                    commandMessage.Result = true;
                    break;
                case RedisCommand.StringBitCount:
                    commandMessage.Result = await db.StringBitCountAsync(commandMessage.Key, commandMessage.Value.Start, commandMessage.Value.End, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitOperation:
                    commandMessage.Result = await db.StringBitOperationAsync(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.First, commandMessage.Value.Second, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitOperationArray:
                    commandMessage.Result = await db.StringBitOperationAsync(commandMessage.Value.Operation, commandMessage.Value.Destination, commandMessage.Value.Keys, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitPosition:
                    commandMessage.Result = await db.StringBitPositionAsync(commandMessage.Key, commandMessage.Value.Bit, commandMessage.Value.Start, commandMessage.Value.End, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringGetBit:
                    commandMessage.Result = await db.StringGetBitAsync(commandMessage.Key, commandMessage.Value, commandFlags).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSetBit:
                    commandMessage.Result = await db.StringSetBitAsync(commandMessage.Key, commandMessage.Value.Offset, commandMessage.Value.Bit, commandFlags).ConfigureAwait(false);
                    break;
                default:
                    throw new InvalidOperationException("execute async command do not support this:" + command.ToString());
            }
            return message.Result == null ? default(TResult) : message.Result;
        }
    }
}
